﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;

namespace BioCompEx3
{
    public partial class BioCompEx3UI : Form
    {
        private ANN annNeuralNetwork;
        private DB dbInputDB;
        private const int InputNuronsCount = 39;

        public BioCompEx3UI()
        {
            InitializeComponent();            
        }

        /*Creates a DB and ANN objects and uses them to perform ANN learning
         * 
         * Returns - The percentage of correct results
         */ 
        public double PerformLearning(string datafileName, 
            string inputFilename, 
            int learnPercentage, 
            int inputNeuronsCount, 
            int firstLayerNeuronsCount, 
            int secondLayerNeuronsCount,
            double alpha)
        {
            dbInputDB = new DB(datafileName, inputFilename, learnPercentage);
            annNeuralNetwork = new ANN(dbInputDB, inputNeuronsCount, firstLayerNeuronsCount, secondLayerNeuronsCount, alpha); 

            long lAmmountOfCorrectResults = annNeuralNetwork.performLearning();
            long lAmmountOfTupples = dbInputDB.lAmmountOfValidationTupples;

            double correctValidationPercentage = (double)((double)lAmmountOfCorrectResults / (double)lAmmountOfTupples);
            return correctValidationPercentage;
        }

        /*Uses the existing ANN to get outputs for each of the Test set's tupple
         * 
         * Returns - An array of int values, each value can be 1 / 0, where 1 indicates a profitable organization
         */ 
        public ArrayList TestNeuralNetwork()
        {
            return annNeuralNetwork.performTest();
        }

        //runs the neural network learning procedure
        //displays the accuracy result of running the validation set after learning
        private void btnLearn_Click(object sender, EventArgs e)
        {
            //for CTOR resons the following fields are disabled once we start running
            tbx1stLayerNurons.Enabled = false;
            tbx2ndLayerNurons.Enabled = false;
            tbxLearnPercentage.Enabled = false;
            tbxDataFileName.Enabled = false;
            tbxInputFileName.Enabled = false;
            tbxOutputFileName.Enabled = false;
            tbxAlpha.Enabled = false;
            //init result labels
            lblTestStatus.Text = "   ";
            lblLearnStatus.Text = "Processing... Please Wait";
            double accuracy = PerformLearning(tbxDataFileName.Text, 
                tbxInputFileName.Text, 
                Convert.ToInt32(tbxLearnPercentage.Text), 
                InputNuronsCount, 
                Convert.ToInt32(tbx1stLayerNurons.Text), 
                Convert.ToInt32(tbx2ndLayerNurons.Text),
                Convert.ToDouble(tbxAlpha.Text));
            accuracy = Math.Round(accuracy, 2);
            lblLearnStatus.Text = "Done!";
            tbxAccuracyLevel.Text = (accuracy*100).ToString() + "%";
            btnTest.Enabled = true;
        }

        //runs the testing procedure on the second file, results are printed to output file
        private void btnTest_Click(object sender, EventArgs e)
        {
            lblTestStatus.Text = "Processing... Please Wait";
            ArrayList results = TestNeuralNetwork();
            StreamWriter output = new StreamWriter(tbxOutputFileName.Text);
            foreach (int result in results)
            {
                output.WriteLine(result);
            }
            output.Close();
            lblTestStatus.Text = "Done! Results printed to output file";
        }
    }
}
